#include "Game.hh"
#include <iostream>

Game::Game() {
    createRooms();
    connectRooms();
    addItemsAndEnemies();
    player = new Character("Hero", "A brave adventurer", 100, 15, 10);
    currentRoom = startingChamber;
    menu = new Menu(currentRoom, player);
}

Game::~Game() {
    delete player;
    delete startingChamber;
    delete corridor;
    delete treasureRoom;
    delete ancientTemple;
    delete healingRoom;
    delete damageRoom;
    delete menu;
}

Game::Game(const Game& other) {
    // 深拷贝所有动态成员
    player = new Character(*other.player);    // 假设Character有拷贝构造函数
    startingChamber = new Room(*other.startingChamber);
    corridor = new Room(*other.corridor);
    treasureRoom = new Room(*other.treasureRoom);
    ancientTemple = new Room(*other.ancientTemple);
    healingRoom = new SpecialRoom(*other.healingRoom);
    damageRoom = new SpecialRoom(*other.damageRoom);
    menu = new Menu(*other.menu);
    
    // 关联房间（需根据实际Room类的设计实现连接逻辑）
    connectRooms();
    
    // 设置当前房间（需根据拷贝后的房间指针调整）
    currentRoom = startingChamber;  // 假设起始房间是startingChamber
}
Game& Game::operator=(const Game& other) {
    if (this != &other) {
        // 释放原有资源
        delete player;
        delete startingChamber;
        delete corridor;
        delete treasureRoom;
        delete ancientTemple;
        delete healingRoom;
        delete damageRoom;
        delete menu;
        
        // 深拷贝新资源
        player = new Character(*other.player);
        startingChamber = new Room(*other.startingChamber);
        corridor = new Room(*other.corridor);
        treasureRoom = new Room(*other.treasureRoom);
        ancientTemple = new Room(*other.ancientTemple);
        healingRoom = new SpecialRoom(*other.healingRoom);
        damageRoom = new SpecialRoom(*other.damageRoom);
        menu = new Menu(*other.menu);
        
        // 重新连接房间
        connectRooms();
        currentRoom = startingChamber;
    }
    return *this;
}
void Game::createRooms() {
    startingChamber = new Room("You find yourself in a dimly lit chamber.");
    corridor = new Room("You enter a narrow corridor with strange markings on the walls.");
    treasureRoom = new Room("You are in a room filled with glittering treasures.");
    ancientTemple = new Room("You have entered the ancient temple, the final resting place of the Sword of Light.");
    healingRoom = new SpecialRoom("You are in a serene, healing room.", 10);
    damageRoom = new SpecialRoom("You are in a dark, ominous room.", -5);
}

void Game::connectRooms() {
    startingChamber->setNorth(corridor);
    corridor->setSouth(startingChamber);
    corridor->setNorth(treasureRoom);
    treasureRoom->setSouth(corridor);
    treasureRoom->setNorth(ancientTemple);
    ancientTemple->setSouth(treasureRoom);
    startingChamber->setEast(healingRoom);
    healingRoom->setWest(startingChamber);
    corridor->setWest(damageRoom);
    damageRoom->setEast(corridor);
}

void Game::addItemsAndEnemies() {
    startingChamber->addItem(new Item("Magic Amulet", "+50 Health", 50, 0, 0));
    startingChamber->addItem(new Item("Iron Sword", "+20 Attack", 0, 20, 0));
    corridor->addItem(new Item("Wooden Shield", "+10 Defense", 0, 0, 10));
    corridor->addItem(new Item("Healing Potion", "+100 Health", 100, 0, 0));
    treasureRoom->addItem(new Item("Gold Coin", "+30 Attack", 0, 30, 0));
    ancientTemple->addItem(new Item("Sword of Light", "+20 Attack +20 Defense", 0, 20, 20));
    startingChamber->addEnemy(new Goblin());
    corridor->addEnemy(new Goblin());
    corridor->addEnemy(new Goblin());
    corridor->addEnemy(new Troll());
    damageRoom->addEnemy(new TungTungTung_sahur());    
    treasureRoom->addEnemy(new FrostQueen());
    ancientTemple->addEnemy(new Wizard());
}


void Game::gameLoop() {
    while (player->isAlive()) {
        int choice = menu->getPlayerChoice();

        switch (choice) {
            case 1:
                if (!currentRoom->getEnemies().empty()) {
                    Menu::clearScreen();
                    std::cout << "=== AREA LOCKED ===" << std::endl;
                    std::cout << "Eliminate all hostiles to proceed" << std::endl;
                    std::cout << "Press any key to access main menu: ";
                    std::cin.ignore();
                    std::cin.get();
                    break;
                }
                if (currentRoom->hasNorth()) {
                    currentRoom = currentRoom->getNorth();
                    currentRoom->generateRandomLoot(); // Generate random loot
                    menu->setCurrentRoom(currentRoom);
                } else {
                    Menu::clearScreen();
                    std::cout << "=== Invalid Direction ===" << std::endl;
                    std::cout << "You can't go that way." << std::endl;
                    std::cout << "Press any key to return to the main menu: ";
                    std::cin.ignore();
                    std::cin.get();
                }
                break;
            case 2:
                if (!currentRoom->getEnemies().empty()) {
                    Menu::clearScreen();
                    std::cout << "=== AREA LOCKED ===" << std::endl;
                    std::cout << "Eliminate all hostiles to proceed" << std::endl;
                    std::cout << "Press any key to access main menu: ";
                    std::cin.ignore();
                    std::cin.get();
                    break;
                }
                if (currentRoom->hasSouth()) {
                    currentRoom = currentRoom->getSouth();
                    currentRoom->generateRandomLoot(); // Generate random loot
                    menu->setCurrentRoom(currentRoom);
                } else {
                    Menu::clearScreen();
                    std::cout << "=== Invalid Direction ===" << std::endl;
                    std::cout << "You can't go that way." << std::endl;
                    std::cout << "Press any key to return to the main menu: ";
                    std::cin.ignore();
                    std::cin.get();
                }
                break;
            case 3:
                if (!currentRoom->getEnemies().empty()) {
                    Menu::clearScreen();
                    std::cout << "=== AREA LOCKED ===" << std::endl;
                    std::cout << "Eliminate all hostiles to proceed" << std::endl;
                    std::cout << "Press any key to access main menu: ";
                    std::cin.ignore();
                    std::cin.get();
                    break;
                }
                if (currentRoom->hasEast()) {
                    currentRoom = currentRoom->getEast();
                    currentRoom->generateRandomLoot(); // Generate random loot
                    menu->setCurrentRoom(currentRoom);
                } else {
                    Menu::clearScreen();
                    std::cout << "=== Invalid Direction ===" << std::endl;
                    std::cout << "You can't go that way." << std::endl;
                    std::cout << "Press any key to return to the main menu: ";
                    std::cin.ignore();
                    std::cin.get();
                }
                break;
            case 4:
                if (!currentRoom->getEnemies().empty()) {
                    Menu::clearScreen();
                    std::cout << "=== AREA LOCKED ===" << std::endl;
                    std::cout << "Eliminate all hostiles to proceed" << std::endl;
                    std::cout << "Press any key to access main menu: ";
                    std::cin.ignore();
                    std::cin.get();
                    break;
                }
                if (currentRoom->hasWest()) {
                    currentRoom = currentRoom->getWest();
                    currentRoom->generateRandomLoot(); // Generate random loot
                    menu->setCurrentRoom(currentRoom);
                } else {
                    Menu::clearScreen();
                    std::cout << "=== Invalid Direction ===" << std::endl;
                    std::cout << "You can't go that way." << std::endl;
                    std::cout << "Press any key to return to the main menu: ";
                    std::cin.ignore();
                    std::cin.get();
                }
                break;
            case 5:
                menu->displayTakeItemMenu();
                break;
            case 6:
                menu->displayAttackEnemyMenu();
                break;
            case 7:
                player->heal(50); // Heal 50 HP
                std::cout << "You healed 50 HP." << std::endl;
                break;
            case 8:
                menu->displayInventoryMenu();
                break;
            case 9:
                menu->displayStatsMenu();
                break;
            case 10:
                std::cout<<"Exiting game..."<<std::endl;
                return;
            default:
                std::cout << "Invalid choice. Please try again." << std::endl;
                break;
        }

        if (currentRoom == ancientTemple && currentRoom->getEnemies().empty()) {
            std::cout << "Congratulations! You have found the Sword of Light and defeated the Dark Sorcerer!" << std::endl;
            return;
        }
        if (!player->isAlive()){
            std::cout << "Game Over! You have been slain by the Dark Sorcerer." << std::endl;
            std::string input;
            std::cout << "Would you like to play again? (y/n)" << std::endl;
            std::cin >> input;
            if (input == "y") {
                std::cout << "Restarting game..." << std::endl;
                Game game2;
                game2.start();
                
            } else {
                std::cout << "Thank you for playing!" << std::endl;
                return;
            }
        }
    }
}

void Game::start() {
    gameLoop();
}